#include "bloques.h"
#include "ficheros_basico.h"
#include "ficheros.h"

#include <string.h>


int mi_write_f(unsigned int ninodo, const void *buf, unsigned int offset, unsigned int nbytes){

	unsigned char buff[tam_bloq];
	memset(buff, '\0', tam_bloq);
	
	int blescrito = 0;
	
	//Primer bloque logico donde vamos escribiremos primero
	int blogico = offset/ tam_bloq;
	int bfisico = traducir_bloque_inodo(ninodo, blogico, 1);
	
	//Ultimo bloque logico
	int blultimo = (offset - nbytes - 1)/tam_bloq;	//Sobra
	
	int pbyte = offset % tam_bloq;
	
	//Cantidad bloques intermedios
	int blmedio = (nbytes - tam_bloq - pbyte) / tam_bloq;
	
	//Cantidad de bytes del ultimo bloque a escribir 
	int byultbl = (nbytes - tam_bloq - pbyte) % tam_bloq;

	int i;
	
	inodo inod;
	
	//Solo escribimos en el primer bloque
	if (nbytes <= (tam_bloq - pbyte)){
				
		if (bread(bfisico, buff) == -1){
			printf("ficheros.c -> mi_write_f => Error al leer el bloque %d \n", bfisico);
			return -1;
		}
		memcpy(&buff[pbyte], buf, nbytes);
		if (bwrite(bfisico, buff) == -1){
			printf("ficheros.c -> mi_write_f = >Error al escribir el bloque %d \n", bfisico);
		}
		blescrito = nbytes;
		
		inod = leer_inodo(ninodo);
		
		inod.tamano = inod.tamano + blescrito;
		if (escribir_inodo(inod, ninodo) == -1){
			printf("ficheros.c -> mi_write_f => Error al escribir inodo %d en mi_write_f -> ficheros.c\n ", ninodo);
			return -1;
		}
		
		return blescrito;
			
	} else if ( nbytes > (tam_bloq - pbyte)){		//distinguimos los restos de casos
		
		//Primer bloque
		if (bread(bfisico, buff) == -1){
			printf("ficheros.c -> mi_write_g => Error al leer el bloque %d \n", bfisico);
			return -1;
		}
		memcpy(&buff[pbyte], buf, tam_bloq - pbyte);
		if (bwrite(bfisico, buff) == -1){
			printf("ficheros.c -> mi_write_f => Error al escribir en el bloque %d \n", bfisico);
		}
		blescrito = tam_bloq - pbyte;
		pbyte++; //preguntar pepe
		memset(buff, '\0', tam_bloq);
	
		//Caso bloques intermedios
		for(i = 0; i < blmedio; i++){
			memcpy(&buff, buf + blescrito, tam_bloq);
			bfisico = traducir_bloque_inodo(ninodo, blogico, 1);
			if (bwrite(bfisico, buff) == -1){
				printf("ficheros.c -> mi_write_f => Eror al escribir en el bloque %d \n", bfisico);
				return -1;
			}
			blescrito = blescrito + tam_bloq;
			pbyte++; //preguntar pepe
			memset(buff, '\0', tam_bloq);
		}
		
		//Ultimo bloque
		if (byultbl != 0){
			memset(buff, '\0', tam_bloq);
			bfisico = traducir_bloque_inodo(ninodo, blogico, 1);
			if (bread(bfisico, buff) == -1){
				printf("ficheros.c -> mi_write_f => Error al leer el bloque %d \n", bfisico);
				return -1;
			}
			memcpy(&buff, buf + blescrito, byultbl);
			if (bwrite(bfisico, buff) == -1){
				printf("fichero.c -> mi_write_f => Error al escribir en el bloque %d \n", bfisico);
				return -1;
			}
			blescrito = blescrito + byultbl;
		
		}
		
		inod = leer_inodo(ninodo);
		inod.tamano = inod.tamano + blescrito;
		if (escribir_inodo(inod, ninodo) == -1){
			printf("ficheros.c -> mi_write_f => Error al escribir inodo %d en mi_write_f -> ficheros.c \n", ninodo);
			return -1;
		}
		
		return blescrito;
	}
}

int mi_read_f(unsigned int ninodo, void *buf, unsigned int offset, unsigned int nbytes){

	unsigned char buff[tam_bloq];
	memset(buff, '\0', tam_bloq);
	int bleido = 0;
	
	int blogico = offset / tam_bloq;
	int bfisico = traducir_bloque_inodo(ninodo, blogico, 0);

	int pbyte = offset % tam_bloq;
	
	int blmedio = (nbytes - tam_bloq - pbyte) / tam_bloq;

	int blultimo = (nbytes - tam_bloq - pbyte) % tam_bloq;

	int i;
	
	//Leemos el primer bloque
	if (nbytes <= (tam_bloq - pbyte)){
		if (bread(bfisico, buff) == -1){
			printf("ficheros.c -> mi_read_f => Error al leer el bloque %d \n", bfisico);
			return -1;
		}
		memcpy(buf, &buff[pbyte], nbytes);
		bleido = nbytes;
		
		return bleido;
	} else if(nbytes > (tam_bloq - pbyte)){	//distinguimos el resto de casos
	
		//Primer bloque
		if (bread(bfisico, buff) == -1){
			printf("ficheros.c -> mi_read_f => Error al leer el bloque %d \n", bfisico);
			return -1;
		}
		memcpy(buf, &buff[pbyte], tam_bloq - pbyte);
		bleido = tam_bloq - pbyte;
	
		//Caso bloques intermedios
		for (i = 0; i < blmedio; i++){
			blogico++;
			bfisico = traducir_bloque_inodo(ninodo, blogico, 0);
			if (bread(bfisico, buff) == -1){
				printf("ficheros.c -> mi_read_f => Error al leer el bloque %d \n", bfisico);
				return -1;
			}
			memcpy(buf + bleido, &buff, tam_bloq);
			bleido = bleido + tam_bloq;
			memset(buff, '\0', tam_bloq);
		}
		
		//Ultimo bloque
		if (blultimo != 0){
			blogico++;
			memset(buff, '\0', tam_bloq);
			bfisico = traducir_bloque_inodo(ninodo, blogico, 0);
			if (bread(bfisico, buff) == -1){
				printf("ficheros.c -> mi_read_f => Error al leer el bloque %d \n", bfisico);
				return -1;
			}
			memcpy(buf, &buff + bleido, blultimo);
			bleido = bleido + blultimo;
		}
		
		return bleido;
		
	}
}

int mi_truncar_f(unsigned int ninodo, unsigned int nbytes){
	
	int bloque, i, blleidos = 0; 
	inodo inod;
	
	inod = leer_inodo(ninodo);
	
	if (nbytes > 0){
		
		if (nbytes % tam_bloq == 0){
			bloque = nbytes / tam_bloq;
		} else {
			bloque = nbytes / tam_bloq + 1;
		}
		
		//mirar for pepote
		for (i = 0; i <= inod.bloques_asignados; i++){
			
			if (traducir_bloque_inodo(ninodo, i, 0) > 0){
				blleidos++;
			}
			
			if (bloque == blleidos){
				liberar_inodo(ninodo);
				
				inod = leer_inodo(ninodo);
				
				inod.tamano = nbytes;
				inod.fechaMod = time(NULL);
				if (escribir_inodo(inod, ninodo) == -1){
					printf("ficheros.c -> mi_truncar_f => Error al escribir inodo %d \n", ninodo);
					return -1;
				}
				return 0;
			}
			
		}

	} else if (nbytes == 0){
			liberar_inodo(ninodo);
	} else {
		printf("ficheros.c -> mi_truncar_f => Error, No se puede truncar el fichero\n");
		return -1;
	}
	
}


int mi_stat_f(unsigned int ninodo, STAT *p_stat){

	inodo inod;
	
	inod = leer_inodo(ninodo);

	p_stat->tipo = inod.tipo;
	p_stat->tamanyo = inod.tamano;
	p_stat->fecha_crea = inod.fechaMod; 
	p_stat->fecha_mod = inod.fechaMod;
	p_stat->bloques_asignados = inod.bloques_asignados;
	
	return 0;
}



